package net.alteiar.ui.editor.tools;

import java.awt.Color;
import java.awt.Point;
import java.util.HashSet;
import java.util.Stack;

import net.alteiar.images.metadata.ImageInfo;

public class Fill extends ImageInfoTool {

	private int border;
	private int value;

	public Fill(ImageInfo info, ImageInfo tmp) {
		super(info, tmp);

		value = Color.BLACK.getRGB();
		border = Color.BLACK.getRGB();
	}

	public int getValue() {
		return value;
	}

	public void setValue(int value) {
		this.value = value;
	}

	public int getBorder() {
		return border;
	}

	public void setBorder(int border) {
		this.border = border;
	}

	@Override
	protected boolean canDoTmp() {
		return false;
	}

	@Override
	public void doAction(ImageInfo info, Point imgPos) {
		nonRecursiveFill(info, imgPos, border, value);
	}

	public static void nonRecursiveFill(ImageInfo colors, Point begin,
			int borderColor, int newColor) {
		Stack<Point> pending = new Stack<Point>();
		pending.push(begin);

		HashSet<Point> visited = new HashSet<>();
		while (!pending.empty()) {
			Point p = pending.pop();
			if (!visited.contains(p)) {
				visited.add(p);

				if (isLegal(colors, p.x, p.y)
						&& colors.getValue(p.x, p.y) != borderColor) {
					colors.setBatchValue(p.x, p.y, newColor);
					pending.push(new Point(p.x - 1, p.y));
					pending.push(new Point(p.x + 1, p.y));
					pending.push(new Point(p.x, p.y - 1));
					pending.push(new Point(p.x, p.y + 1));
				}
			}
		}
		colors.endBatchModification();
	}

	private static boolean isLegal(ImageInfo array, int i, int j) {
		if (i < 0 || j < 0)
			return false;
		if (i >= array.getWidthSquare() || j >= array.getHeightSquare())
			return false;
		return true;
	}
}
